package com.nexus.all.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.nexus.all.config.SpringParameterConfig;
import com.nexus.all.constants.RedisKeyNexus;
import com.nexus.all.dto.UserTimeMailDTO;
import com.nexus.all.manager.UserManager;
import com.nexus.all.manager.UserTimeMailManager;
import com.nexus.all.model.User;
import com.nexus.all.model.UserTimeMail;
import com.nexus.all.service.UserTimeMailService;
import com.nexus.bean.utils.*;
//import com.nexus.lock.RedissonLock;
import com.nexus.mail.dto.SendEmailApiDTO;
import com.nexus.mail.service.IMailService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zxt
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserTimeMailServiceImpl implements UserTimeMailService {

    private final UserTimeMailManager userTimeMailManager;
    private final UserManager userManager;
    private final IMailService mailService;
    //private final RedissonLock redissonLock;
    private final SpringParameterConfig springParameterConfig;

    @Override
    @DSTransactional
    public void dealSendUserTimeMail() {
        /*if (!redissonLock.lock(RedisKeyNexus.getLock("dealSendUserTimeMail", null), 0, 10)) {
            log.info("时间邮件发送锁被占用");
            return;
        }*/
        try {
            sendUserTimeMail();
        } finally {
            //redissonLock.release(RedisKeyNexus.getLock("dealSendUserTimeMail", null));
        }
    }

    @Override
    @DSTransactional
    public void saveTimeMail(UserTimeMailDTO dto) {
        UserTimeMail userTimeMail = BeanUtils.beanCopy(dto, UserTimeMail.class);
        //生成加密盐值
        userTimeMail.setContentSalt(UuIdUtils.randomUUID(Boolean.TRUE));
        //使用Aes进行加密存储
        String decryptedContent = RSAUtil.decryptByPrivateKey(dto.getContent(), springParameterConfig.getUserTimeMailPrivateKey());
        userTimeMail.setContent(AesUtils.encryption(decryptedContent, userTimeMail.getContentSalt()));
        userTimeMail.setIsSendArrive(Boolean.FALSE);
        userTimeMailManager.save(userTimeMail);
    }

    private void sendUserTimeMail() {
        List<UserTimeMail> userTimeMailList = userTimeMailManager.getNeedSendList();
        if (CollectionsUtil.isEmpty(userTimeMailList)) {
            return;
        }

        List<Long> userIds = userTimeMailList.stream().map(UserTimeMail::getUserId).distinct().collect(Collectors.toList());
        List<User> userList = userManager.listByIds(userIds);
        Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        for (UserTimeMail userTimeMail : userTimeMailList) {
            log.info("发送时间邮件 时间邮件id:{}", userTimeMail.getId());
            SendEmailApiDTO emailApiDTO = new SendEmailApiDTO();
            emailApiDTO.setToEmail(userTimeMail.getSendMail());
            emailApiDTO.setSubject("您有一封时间邮件已抵达~ 时间来自" + userTimeMail.getCreateTime());
            emailApiDTO.setContent(userTimeMail.getContentTitle() + "\n\n" + AesUtils.decrypt(userTimeMail.getContent(), userTimeMail.getContentSalt()));
            Boolean isSuccess = mailService.sendCommonMail(emailApiDTO);
            if (Objects.nonNull(isSuccess) && isSuccess) {
                userTimeMailManager.updateSendArrive(userTimeMail.getId());
                //为创建时间邮件的人发送 成功通知
                User user = userMap.get(userTimeMail.getUserId());
                if (Objects.nonNull(user)) {
                    SendEmailApiDTO sendEmailApiDTO = new SendEmailApiDTO();
                    sendEmailApiDTO.setToEmail(user.getEmail());
                    sendEmailApiDTO.setSubject("您设置的时间邮件已成功抵达~ 时间来自" + userTimeMail.getCreateTime());
                    sendEmailApiDTO.setContent("邮件标题为：" + userTimeMail.getContentTitle());
                    mailService.sendCommonMail(sendEmailApiDTO);
                }
            }
        }
    }
}
